<template>
  <div class="issued-rules-history">
    <search-table
      :columns="columns"
      :data="issuedRuleList"
      :total="total"
      :page.sync="pageIndex"
      :size.sync="pageSize"
      @change-page="changePageNow"
      @change-size="changePageSize"
    >
      <!-- <Alert type="warning" show-icon slot="alert" v-if="onlineMode === 1 && type === 2 && !vpn">
        <p>
          线上夺旗赛会额外展示nginx-dns服务器、公网路由的规则下发情况，该机器属于中立方，任何团队都能在首页查询到该机器的记录
        </p>
      </Alert> -->
      <template slot="select-group">
        <Select filterable
          v-model="partyId"
          @on-change="changePageNow(1)"
          transfer
          filterable
          clearable
          placeholder="请选择团队"
        >
          <Option
            v-for="item in teamOptions"
            :value="item.partyId"
            :key="item.id"
            :title="item.name"
            >{{ item.name }}</Option
          >
        </Select>
        <Button type="primary" ghost icon="ios-nuclear-outline" @click="issuedRules" class="mr15"
          >下发规则</Button
        >
      </template>
    </search-table>
    <Modal v-model="showDetail" :footer-hide="true" class="rules-detail" :title="detailModalTitle">
      <div class="rules-detail-text">{{ detailContent }}</div>
    </Modal>
    <Modal
      v-model="showHistroy"
      :footer-hide="true"
      :width="70"
      @on-visible-change="visibleChange"
      :title="modalTitle"
    >
      <Table :columns="histroyColumns" :data="histroyList"></Table>
      <Page
        :total="histroyTotal"
        show-elevator
        show-total
        :current="histroyPageIndex"
        @on-change="changeHistroyPageNow"
        style="margin-top: 20px; text-align: right;"
      />
    </Modal>
    <Modal v-model="reDisRouterModal" title="重新下发路由" :mask-closable="false" :width="700">
      <label color="blue" style="margin-bottom:20px;display: inline-block;vertical-align: middle;"
        >路由规则:
      </label>
      <Input
        v-model.trim="routerContent"
        placeholder="路由规则"
        type="textarea"
        style="margin-bottom: 20px;"
        :autosize="{ minRows: 5, maxRows: 10 }"
      ></Input>
      <div slot="footer">
        <Button @click="reDisRouterModal = false">取消</Button>
        <Button @click="reDisRouter" type="primary" :loading="reDisRouterLoading">确定</Button>
      </div>
    </Modal>
  </div>
</template>

<script>
import SearchTable from '@/components/SearchTable/SearchTable'
import { getIssuedRulesRecord, executeScriptAgain, deleteScript, issuedRules } from '@/api/drill'
import { queryDeployedVms } from '@/api/drill_compete'
import { getaccessgrouplist } from '@/api/access_new'
import teamMixin from '@/mixin/groupMixin'
import { decode, encode } from '@/libs/utils'

export default {
  name: 'issued-rules-history',
  mixins: [teamMixin],
  components: {
    SearchTable
  },
  props: {
    onlineMode: {
      type: Number,
      default: 0
    },
    disabledAllBtn: {
      // 是否禁用相关功能
      type: Boolean,
      default: false
    },
    type: {
      // 场景类型 0:对抗演练、1:攻防赛、2:夺旗赛、3:知识赛、4:渗透演练、5:护网演练、6:应急防御演练、7:综合演练
      type: Number,
      default: 5
    },
    deployMode: {
      // 部署模式 1:数据通道模式 2:路由模式
      type: Number,
      default: 1
    },
    hwType: {
      type: Number,
      default: 0
    },
    vpn: {
      type: Boolean,
      default: false
    },
    ctfOnlineMode: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      reDisRouterLoading: false,
      routerContent: '',
      curDevice: {},
      reDisRouterModal: false,
      showDetail: false,
      modalTitle: '',
      detailModalTitle: '',
      detailContent: '',
      total: 0, // 总数据量
      pageSize: 10, // 分页大小
      pageIndex: 1, // 当前页
      partyId: '',
      teamOptions: [],
      columns: [
        {
          placement: 'top-left',
          title: '路由名称',
          key: 'name',
          align: 'center',
          tooltip: true,
          width: 230
        },
        {
          title: '团队名称',
          width: 150,
          tooltip: true,
          key: 'partyName'
        },
        {
          title: '下发记录',
          width: 140,
          key: 'action',
          opList: [
            {
              txt: '查看',
              fun: this.getHistroy
            }
          ]
        }
      ],
      showHistroy: false,
      histroyTotal: 0, // 历史记录总记录数
      histroyPageIndex: 1, // 历史记录当前页
      histroyPageSize: 10, // 历史记录分页大小
      histroyList: [], // 路由历史纪录
      issuedRuleList: [], // 下发规则记录
      histroyColumns: [
        {
          title: '规则名称',
          key: 'scriptName',
          tooltip: true
        },
        {
          title: '下发时间',
          key: 'created',
          tooltip: true
        },
        {
          title: '脚本内容',
          key: 'contentFilter',
          tooltip: true,
          render: (h, params) => {
            return h(
              'Tag',
              {
                props: {
                  color: 'blue'
                },
                nativeOn: {
                  click: () => {
                    this.showDel(params.row)
                  }
                }
              },
              params.row.contentFilter
            )
          }
        },
        {
          title: '状态',
          key: 'statusFilter',
          render: (h, params) => {
            let status = params.row.status
            return h(
              'Tag',
              {
                props: {
                  color: this.scriptStatusEscape(status)
                },
                style: {
                  cursor: 'default'
                }
              },
              this.scriptStatusEscape(status, 'text')
            )
          }
        },
        {
          title: '错误码',
          key: 'errMsg',
          tooltip: true
        },
        {
          title: '操作',
          key: 'os',
          render: (h, params) => {
            return h(
              'Button',
              {
                props: {
                  type: 'primary',
                  size: 'small'
                },
                on: {
                  click: () => {
                    this.reDisRouterModal = true
                    this.routerContent = params.row.contentFilter
                    this.curDevice = params.row
                  }
                }
              },
              '重新下发'
            )
          }
        }
      ]
    }
  },
  mounted() {
    this.getIssuedRuleList()
    this.getAccessGroupList()
  },
  computed: {
    vmTypes() {
      if (this.type === 5) {
        // 护网演练查询PRT路由
        if (this.hwType == 2) {
          return ['PRT', 'DRT']
        } else if (this.hwType == 4) {
          // 后台存在差异，修修改改，重新加一个判断出来（如稳定，无异议，可以把这个合到上一个条件里）
          return ['PRT', 'DRT']
        } else {
          return ['PRT']
        }
      } else if (this.type === 2 && this.onlineMode === 1) {
        // 线上夺旗赛，域名模式只要查询DRT类型路由，vpn模式PRT、DRT都要查询，公网路由由其他接口额外查询
        return this.vpn ? ['PRT', 'DRT'] : ['DRT']
      } else if ([1, 2, 5, 8, 9].includes(this.type) && this.deployMode === 2) {
        // 攻防赛、线下夺旗赛、护网、攻防赛plus的路由模式，PRT、DRT都要查询
        return ['PRT', 'DRT']
      } else {
        // 其他暂定查询DRT路由
        return ['DRT']
      }
    }
  },
  methods: {
    issuedRules() {
      //             this.issuedLoading = true;
      issuedRules(this.$route.query.id)
        .then(async ({ code, message }) => {
          if (code !== 1) {
            // this.cancelBtnLoading();
            this.$Message.warning(message)
          } else {
            this.$Message.success('下发规则成功')
            // self->TabPane->Tabs->hwDrillDetail，所以需要三个$parent
            //                         this.$parent.$parent.$parent.changePreDefault('routerRules');
          }
        })
        .catch(() => {
          this.cancelBtnLoading()
          this.$Message.error(`下发规则异常`)
        })
    },

    // 重新下发规则
    reDisRouter() {
      this.reDisRouterLoading = true
      let device = this.curDevice
      let executionIns = [
        {
          content: encode(this.routerContent),
          deviceId: device.deviceId,
          metadata: {},
          name: device.scriptName,
          projectId: this.$route.query.prjid,
          ready: true
        }
      ]
      executeScriptAgain(executionIns)
        .then(({ code, message }) => {
          if (code == 1) {
            this.$Message.info('执行规则成功，等待规则生效')
            // 执行完成，将原来的数据删除掉，跳转至第一页
            deleteScript(this.curDevice.scriptId)
              .then()
              .finally(() => {
                this.changeHistroyPageNow(1)
              })
            this.reDisRouterModal = false
          } else {
            this.$Message.warning(message)
            this.reDisRouterLoading = false
          }
        })
        .catch(() => {
          this.$Message.error('重新下发规则异常')
        })
    },
    // 获取接入组列表
    getAccessGroupList() {
      let params = {
        pageIndex: 1,
        pageSize: 2147483647,
        testId: this.$route.query.id
      }
      getaccessgrouplist(params).then((data) => {
        if (data.code == 1) {
          this.teamOptions = data.data.items || []
          if (this.type === 5) {
            this.teamOptions = this.teamOptions.filter((item) => item.name !== '目标方管理员组')
          }
        } else {
          this.$Message.warning(data.message)
        }
      })
    },
    // 脚本运行状态编码转义
    scriptStatusEscape(status, type) {
      if (type === 'text') {
        switch (status) {
          case 'success':
            return '成功'
          case 'running':
            return '运行中'
          case 'failed':
            return '失败'
          default:
            return '未下发'
        }
      } else {
        switch (status) {
          case 'success':
            return 'blue'
          case 'running':
            return 'orange'
          case 'failed':
            return 'red'
          default:
            return 'default'
        }
      }
    },
    // 历史记录页面切换
    changeHistroyPageNow(val) {
      this.histroyPageIndex = val
      this.getHistroy(this.histroyParams)
    },
    // 隐藏模态框，清空表单，重置当前页
    visibleChange() {
      clearTimeout(this.histroyListTimer)
      this.histroyPageIndex = 1
    },
    // 查询路由历史记录
    getHistroy(params) {
      clearTimeout(this.histroyListTimer)
      this.histroyParams = params
      getIssuedRulesRecord({
        pageIndex: this.histroyPageIndex,
        pageSize: this.histroyPageSize,
        projectId: this.$route.query.prjid,
        deviceId: params.id
      })
        .then(({ code, message, data }) => {
          if (code !== 1) {
            this.$Message.warning(message)
            return
          }
          this.showHistroy = true
          if (params.name.includes(`${params.partyName}-`)) {
            this.modalTitle = params.name
          } else {
            this.modalTitle = `${params.name}-${params.partyName || '无'}`
          }
          this.histroyTotal = data.total || 0
          let list = data.items || []
          this.histroyList = list.map((item) => {
            item.contentFilter = decode(item.content)
            return item
          })
        })
        .catch(() => {
          this.$Message.error('获取历史记录异常')
        })
        .finally(() => {
          this.histroyListTimer = setTimeout(() => {
            this.getHistroy(this.histroyParams)
          }, 10000)
        })
    },
    // 查看详情
    showDel(params) {
      this.showDetail = true
      this.detailModalTitle = params.scriptName
      this.detailContent = params.contentFilter
    },
    // 修改分页大小
    changePageSize(val) {
      this.pageSize = val
      this.getIssuedRuleList()
    },
    // 修改当前页
    changePageNow(val) {
      this.pageIndex = val
      this.getIssuedRuleList()
    },
    // 获取路由规则下发记录
    getIssuedRuleList() {
      clearTimeout(this.listTimer)
      if (this.onlineMode === 1 && this.type === 2 && this.pageIndex === 1 && !this.vpn && !this.ctfOnlineMode !== 'ip') {
        // 线上夺旗赛域名模式，第一页要额外查询nginx-dns服务器，其他页正常查询
        Promise.all([
          queryDeployedVms(this.$route.query.prjid, {
            pageIndex: this.pageIndex,
            pageSize: 1,
            projectId: this.$route.query.prjid,
            name: 'nginx-dns服务器'
          }),
          queryDeployedVms(this.$route.query.prjid, {
            pageIndex: this.pageIndex,
            pageSize: 1,
            projectId: this.$route.query.prjid,
            name: '公网路由'
          }),
          queryDeployedVms(this.$route.query.prjid, {
            pageIndex: this.pageIndex,
            pageSize: this.pageSize - 2, // 有一条nginx-dns服务器、一条公网路由数据，其他数据查询数量-2
            projectId: this.$route.query.prjid,
            vmTypes: this.vmTypes,
            partyId: this.partyId
          })
        ])
          .then(([res1, res2, res3]) => {
            if (res1.code !== 1 || res2.code !== 1 || res3.code !== 1) {
              this.$Message.warning('获取数据失败')
            } else {
              this.issuedRuleList = (res1.data.items || [])
                .concat(res2.data.items || [])
                .concat(res3.data.items || [])
              this.total = res1.data.total + res2.data.total + res3.data.total
            }
          })
          .catch(() => {
            this.$Message.error('获取路由列表异常')
          })
          .finally(() => {
            this.listTimer = setTimeout(() => {
              this.getIssuedRuleList()
            }, 10000)
          })
      } else {
        queryDeployedVms(this.$route.query.prjid, {
          pageIndex: this.pageIndex,
          pageSize: this.pageSize,
          projectId: this.$route.query.prjid,
          vmTypes: this.vmTypes,
          partyId: this.partyId
        })
          .then(async ({ code, message, data }) => {
            if (code !== 1) {
              this.$Message.warning(message)
            } else {
              this.issuedRuleList = data.items || []
              this.total = data.total
            }
          })
          .catch(() => {
            this.$Message.error('获取路由列表异常')
          })
          .finally(() => {
            this.listTimer = setTimeout(() => {
              this.getIssuedRuleList()
            }, 10000)
          })
      }
    }
  },
  watch: {
    reDisRouterModal(val) {
      // 监控模态框隐藏还是展示
      if (!val) {
        // 隐藏模态框时，重置输入框内容，延迟1秒使“确定”按钮可点
        this.routerContent = ''
        setTimeout(() => {
          this.reDisRouterModal = false
        }, 1000)
      } else {
        // 确保模态框展示，“确认”按钮可点
        this.reDisRouterLoading = false
      }
    }
  },
  beforeDestroy() {
    clearTimeout(this.listTimer)
    clearTimeout(this.histroyListTimer)
  }
}
</script>

<style scoped>
.rules-detail .rules-detail-text {
  white-space: pre-wrap;
  max-height: calc(100vh - 280px);
  height: fit-content;
  overflow: auto;
}
</style>
